﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Wicresoft.EKA.NRemedy.CodeGenerate;

namespace Wicresoft.EKA.NRemedy.CodeGenerator.WinForm
{
    public partial class Main : Form
    {

        private GetFormsThread _getFormsThread;
        private SearchFormThread _searchFormThread;
        private GetFieldsThread _getFieldsThread;
        private CodeGenerateThread _codeGenerateThread;

        public Main()
        {
            InitializeComponent();
            SetUI();
            InitObject();

            this.text_Path.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultDirectory"];
            this.text_Authentication.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultAuthentication"];
            this.text_Password.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultARPwd"];
            this.text_User.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultARUid"];
            this.text_Port.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultPort"];
            this.text_Namespace.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultNameSpace"];
            this.text_Server.Text = System.Configuration.ConfigurationManager.AppSettings["DefaultARServer"];
        }

        private void SetUI()
        {
            this.txtFilterValue.KeyDown += new KeyEventHandler(txtFilterValue_KeyDown);
            this.mitemCopyAll.Click += new EventHandler(mitemCopyAll_Click);
            this.list_Fields.ColumnClick += new ColumnClickEventHandler(ColumnClick);
        }

        private void InitObject()
        {
            _getFormsThread = new GetFormsThread();
            _getFormsThread.GetFormsCompeleted = LoginSuccess;
            _searchFormThread = new SearchFormThread();
            _searchFormThread.SearchCompeleted += new PushFormListDelegate(_searchFormThread_SearchCompeleted);
            _getFieldsThread = new GetFieldsThread();
            _getFieldsThread.GetFieldsCompeleted += new PushFieldsListDelegate(_searchFieldThread_SearchCompeleted);
            _codeGenerateThread = new CodeGenerateThread();
            _codeGenerateThread.GenerateCompeleted += new PushCodeDelegate(_codeGenerateThread_GenerateCompeleted);

        }
        private void login_Click(object sender, EventArgs e)
        {

            GlobalCache.FormCache = null;
            string server = text_Server.Text;
            string user = text_User.Text;
            string password = text_Password.Text;
            string authentication = text_Authentication.Text;
            if (string.IsNullOrWhiteSpace(server) || string.IsNullOrWhiteSpace(user)
                || string.IsNullOrWhiteSpace(password))
            {
                MessageBox.Show("Parameter(Server,User,Password) Is All Necessary");
                return;
            }
            login.Enabled = false;
            ARLoginContext context = new ARLoginContext(server, user, password, ARServerFactoryWithPool.Instance, authentication);
            _getFormsThread.Context = context;
            _searchFormThread.Context = context;
            _getFieldsThread.Context = context;
            _codeGenerateThread.Context = context;
            _getFormsThread.Start();
        }


        private void txtFilterValue_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (_getFormsThread.IsRunning)
                {
                    MessageBox.Show("Reading the form cache. please wait a minute");
                    return;
                }

                if (txtFilterValue.Text.Length >= 3)
                {
                    if (!_searchFormThread.IsRunning)
                    {
                        _searchFormThread.Start(txtFilterValue.Text);
                    }
                    else
                    {
                        MessageBox.Show("Searching  ");
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("at least 3 char");
                }
            }
        }

        private void tvwFormList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            string formName = e.Node.Text;
            _getFieldsThread.Start(formName);
            GlobalCache.FieldIDSelected = new List<uint>();
            GlobalCache.FormName = formName;
            label11.Text = formName;
        }

        // ColumnClick event handler.
        private void ColumnClick(object o, ColumnClickEventArgs e)
        {
            // Set the ListViewItemSorter property to a new ListViewItemComparer 
            // object. Setting this property immediately sorts the 
            // ListView using the ListViewItemComparer object.
            this.list_Fields.ListViewItemSorter = new ListViewItemComparer(e.Column);
        }


        //保留Form 名称和 所有Field,当选定时标注Filed 为已选择。 进而产生
        private void list_Fields_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            var item = e.Item;
            uint id = uint.Parse(item.SubItems[0].Text);
            if (item.Checked)
            {
                GlobalCache.FieldIDSelected.Add(id);
            }
            else
            {
                GlobalCache.FieldIDSelected.Remove(id);
            }
        }


        private void Generate_Click(object sender, EventArgs e)
        {
            if (_getFormsThread.IsRunning)
            {
                MessageBox.Show("Reading the form cache. please wait a minute");
                return;
            }
            if (_searchFormThread.IsRunning)
            {
                MessageBox.Show("Searching  ");
                return;
            }
            if (0 == GlobalCache.FieldIDSelected.Count)
            {
                MessageBox.Show("Please select at least one field.");
                return;
            }
            if (!_codeGenerateThread.IsRunning)
            {
                //do somehing.
                _codeGenerateThread.Start(GlobalCache.FormName, text_Namespace.Text);
            }
            else
            {
                MessageBox.Show("Generating   ");
                return;
            }
        }


        private void mitemCopyAll_Click(object sender, EventArgs e)
        {
            Clipboard.SetDataObject(txtCodeArea.Text, true);
        }

        private void checkBox＿All_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox all = (CheckBox)sender;
            bool isCheck = all.Checked;
            int length = list_Fields.Items.Count;
            for (int i = 0; i < length; i++)
            {
                list_Fields.Items[i].Checked = isCheck;
            }
        }



        private void LoginSuccess(bool isSuccess, string exceptionMessage)
        {
            if (!isSuccess)
            {
                MessageBox.Show(exceptionMessage);
            }
            else
            {
                info.Text = " Finish Read Form Cache " + DateTime.Now.ToString();
            }
            login.Enabled = true;
        }

        private void _searchFormThread_SearchCompeleted(IEnumerable<ARFormDisplay> formList)
        {
            tvwFormList.Nodes.Clear();
            foreach (var f in formList)
            {
                TreeNode tn = new TreeNode(f.Name);
                tvwFormList.Nodes.Add(tn);
            }
        }

        //private IEnumerable<ARFieldDisplay> fieldListCache;

        private void _searchFieldThread_SearchCompeleted(IEnumerable<ARFieldDisplay> fieldList)
        {
            //this.fieldListCache = fieldList;
            list_Fields.Items.Clear();

            foreach (var f in fieldList)
            {
                ListViewItem listItem = new ListViewItem(new string[] { f.ID.ToString(), f.Name, f.Type });
                listItem.SubItems.Add(new ListViewItem.ListViewSubItem(listItem, f.ID.ToString()));
                listItem.SubItems.Add(new ListViewItem.ListViewSubItem(listItem, f.Name));
                listItem.SubItems.Add(new ListViewItem.ListViewSubItem(listItem, f.Type));
                listItem.Checked = true;
                list_Fields.Items.Add(listItem);
            }
        }

        private void _codeGenerateThread_GenerateCompeleted(string code, string error)
        {
            if (string.IsNullOrWhiteSpace(error))
            {

                this.txtCodeArea.Text = code;
                CSharpModelGeneratorDefaultFactory csmgdf = new CSharpModelGeneratorDefaultFactory();
                IGenerateNameResolver gnr = csmgdf.CreateGenerateNameResolver();
                var className = gnr.DefaultClassNameResolver(GlobalCache.FormName);
                string path = string.Empty;
                string pathText = text_Path.Text;


                if (string.IsNullOrWhiteSpace(pathText))
                {
                    path = @"Models/" + className + ".cs";
                }
                else
                {
                    path = pathText + @"/" + className + ".cs";
                }
                if (!isNotOverrideModel.Checked)
                {
                    try
                    {
                        if (File.Exists(path)) File.Delete(path);

                        // Open the stream and write to it.
                        using (FileStream fs = File.OpenWrite(path))
                        {
                            Byte[] info =
                                new UTF8Encoding(true).GetBytes(code);

                            // Add some information to the file.
                            fs.Write(info, 0, info.Length);
                        }

                    }
                    catch (System.UnauthorizedAccessException e)
                    {
                        MessageBox.Show("Please Check Out the File First");
                    }
                }

            }
            else
            {
                this.info.Text = error;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {

            // Show the FolderBrowserDialog.
            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                text_Path.Text = folderBrowserDialog1.SelectedPath;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            Environment.Exit(1);
        }

    }
}
